// ColorSegment.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
using namespace std;

#include <cv.h>
#include <highgui.h>

#define NUMTYPE 4

using namespace cv;

char foodname[10][255] = { "carrot","corn","cookedwhiterice","greenpea"};


int _tmain(int argc, _TCHAR* argv[])
{
		
		char filename[255];

		// let's quantize the hue to 30 levels
		// and the saturation to 32 levels
		int hbins = 30, sbins = 32;
		int histSize[] = {hbins, sbins};
		// hue varies from 0 to 179, see cvtColor
		float hranges[] = { 0, 180 };
		// saturation varies from 0 (black-gray-white) to
		// 255 (pure spectrum color)
		float sranges[] = { 0, 256 };
		const float* ranges[] = { hranges, sranges };
		float* ranges2[] = { hranges, sranges };
		
		MatND rawhist,hist;
		MatND refineHist;
		MatND mergeHist;
		MatND normalizeHist,normalizeMergeHist;
	
		for(int type=0;type<NUMTYPE;type++)
		{

			mergeHist = Mat::zeros(hbins,sbins,CV_32FC1);
			// we compute the histogram from the 0-th and 1-st channels
			int channels[] = {0, 1};
			int scale = 10;
			for(int i=1;i<=20;i++)
			{
				Mat src, hsv;
				sprintf(filename,"D:\\color-sample\\%s\\%d.jpg",foodname[type],i);
				src=imread(filename);

				cvtColor(src, hsv, CV_BGR2HSV);
				calcHist( &hsv, 1, channels, Mat(), // do not use mask
						 hist, 2, histSize, ranges,
						 true, // the histogram is uniform
						 false );
				refineHist = cvCreateMat(hbins,sbins,CV_32FC1);
				for( int h = 0; h < hbins; h++ )
					for( int s = 0; s < sbins; s++ )
					{
						int count=0;
						float cur = hist.at<float>(h, s);
						if(h-1<0 || cur - hist.at<float>(h-1, s) > 100)
							count++;
					
						if(h+1>=hbins || cur -hist.at<float>(h+1, s) > 100)
							count++;
					
						if(s-1<0 || cur -hist.at<float>(h, s-1) > 100)
							count++;
					
						if(s+1>=sbins || cur -hist.at<float>(h, s+1) > 100)
							count++;

						if(count==4) // no neighbour
							refineHist.at<float>(h, s)=0;
						else
							refineHist.at<float>(h, s)=hist.at<float>(h, s);
					
					}

				double maxVal=0;
				minMaxLoc(hist, 0, &maxVal, 0, 0);

			
				Mat histImg = Mat::zeros(sbins*scale, hbins*scale, CV_8UC3);
				Mat refineHistImg = Mat::zeros(sbins*scale, hbins*scale, CV_8UC3);

				normalize(refineHist, normalizeHist);
				double rMaxVal=0;
				minMaxLoc(refineHist, 0, &rMaxVal, 0, 0);

				for( int h = 0; h < hbins; h++ )
				{
					for( int s = 0; s < sbins; s++ )
					{
						mergeHist.at<float>(h, s) += normalizeHist.at<float>(h, s);
						float binVal = hist.at<float>(h, s);
						float rBinVal = refineHist.at<float>(h,s);
						int intensity = 255-(cvRound(binVal*255/maxVal));
						int rIntensity = 255-(cvRound(rBinVal*255/rMaxVal));
						rectangle( histImg, Point(h*scale, s*scale),
									Point( (h+1)*scale - 1, (s+1)*scale - 1),
									Scalar::all(intensity),
									CV_FILLED );
						rectangle( refineHistImg, Point(h*scale, s*scale),
									Point( (h+1)*scale - 1, (s+1)*scale - 1),
									Scalar::all(rIntensity),
									CV_FILLED );
					}
				}

				//namedWindow( "Source", 1 );
				//imshow( "Source", src );

				//namedWindow( "H-S Histogram", 1 );
				//imshow( "H-S Histogram", histImg );

				//namedWindow( "H-S Histogram refine", 1 );
				//imshow( "H-S Histogram refine", refineHistImg );

				//waitKey();

				sprintf(filename,"%s\\histogram%d.jpg",foodname[type],i);
				imwrite(filename,histImg);

			
				sprintf(filename,"%s\\histogram%dr.jpg",foodname[type],i);
				imwrite(filename,refineHistImg);
				//waitKey();


			}

			Mat mergeHistImg = Mat::zeros(sbins*scale, hbins*scale, CV_8UC3);
			double mMaxVal=0;
			minMaxLoc(mergeHist, 0, &mMaxVal, 0, 0);
			Scalar  mMeanVal = mean(mergeHist);
			

			sprintf(filename,"%s.txt",foodname[type]);
			FILE *fp = fopen(filename,"w");

			for( int h = 0; h < hbins; h++ )
			{
				for( int s = 0; s < sbins; s++ )
				{	
					
					float binVal = mergeHist.at<float>(h, s);
					if(binVal < mMeanVal.val[0] )
						 mergeHist.at<float>(h, s)=0;
					binVal = mergeHist.at<float>(h, s);
					//cout << binVal << " ";
					int intensity = 255-(cvRound(binVal*255/mMaxVal));
					rectangle( mergeHistImg, Point(h*scale, s*scale),
								Point( (h+1)*scale - 1, (s+1)*scale - 1),
								Scalar::all(intensity),
								CV_FILLED );

					fprintf(fp,"%f ",binVal);
				}
				fprintf(fp,"\n");
				//cout << endl;
			}
			namedWindow( "merge", 1 );
			imshow( "merge", mergeHistImg );

			sprintf(filename,"%s\\merge-half.jpg",foodname[type]);
			imwrite(filename,mergeHistImg);

			normalize(mergeHist, normalizeMergeHist);

			waitKey();
		}
        return 0;
}